package xin.nick.persistence.core.session;

import xin.nick.persistence.core.entity.Configuration;
import xin.nick.persistence.core.entity.MappedStatement;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author Nick
 * @date 2021/5/6
 * @description  默认的SqlSession实现类
 */
public class DefaultSqlSession implements SqlSession {

    private Configuration configuration;

    public DefaultSqlSession() {

    }

    public DefaultSqlSession(Configuration configuration) {
        this.configuration = configuration;
    }

    @Override
    public <T> T getMapper(Class<?> mapperClass) {

        Object proxyInstance = Proxy.newProxyInstance(DefaultSqlSession.class.getClassLoader(),
                new Class[]{mapperClass}, new InvocationHandler() {

                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                        // 组装 StatementId
                        String methodName = method.getName();
                        String className = method.getDeclaringClass().getName();
                        String statementId = className+"."+methodName;
                        MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId);

                        Object resultObject = null;
                        SimpleExecutor simpleExecutor = new SimpleExecutor();

                        // 总的来说，就是查询和更新
                        switch (mappedStatement.getExecutorType()) {
                            case SELECT:
                                resultObject =  simpleExecutor.query(configuration, mappedStatement, args);
                                break;
                            case DELETE:
                            case INSERT:
                            case UPDATE:
                                resultObject =  simpleExecutor.update(configuration,mappedStatement, args);
                                break;
                            default:

                        }

                        return resultObject;
                    }
                });


        return (T) proxyInstance;
    }
}
